-- Copyright 2016 The Cartographer Authors
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.

include "map_builder.lua"                     --这个文件中的参数控制着后端的参数
include "trajectory_builder.lua"                      --这个文件中的参数控制着前端扫描匹配的参数



--  每次修改完这个.lua脚本，都需要重新编译一下，就是利用工程下面的  catkin_make.sh  脚本重新编译


options = {
  map_builder = MAP_BUILDER,                -- 包含了map_builder.lua的配置信息
  trajectory_builder = TRAJECTORY_BUILDER,  --  包含了 trajectory_builder.lua的配置信息
  
  map_frame = "map",                        -- 地图坐标系的名字
  tracking_frame = "imu_link",              -- 将所有传感器数据转换到这个坐标系下    这里为什么要用imu_link呢？就是因为每个传感器的频率不一样，imu的频率比较高，可以达到100-400HHz，而雷达一般只有10-20Hz，如果这里写成雷达的link的话，那就把imu的link转到雷达上面去了，会耗费很大的转换量的阿，也灭必要，有imu_link就设置为imu，没有就设置为base_link或者footprint
  published_frame = "footprint",            -- cartographer 发布的就是从map_frame->published_frame这样就好理解了     tf: map -> footprint    cartographer 建图节点也会发布一个tf标系，就是 cartographer 发布的 tf 的最下边一个坐标系名字, 就是 bag 文件中 tf  树的最上边的一个坐标系
  odom_frame = "odom",                      -- 里程计的坐标系名字
  provide_odom_frame = false,               -- 是否提供odom的tf，cartographer自己发布一个odom里程计，如果 bag 中有里程计的坐标系, 这个就是  false, 如果没有, 就根据需要决定是否提供里程计的坐标系
                                                                              -- 如果为true,则tf树为map->odom->footprint
                                                                              -- 如果为false tf树为map->footprint
  publish_frame_projected_to_2d = false,    -- 是否将坐标系投影到平面上
  --use_pose_extrapolator = false,            -- 一定要是false，发布tf时是使用pose_extrapolator的位姿，还是前端计算出来的位姿，一般来说使用前端推测出来的位姿，用位子他推测器当里程计不准的时候会有误差

  -- 这三者都是通过topic来订阅的，设置为true就是订阅相应的topic，true时记得在相应的launch中做相应topic的冲映射，可以同时订阅这三个topic数据，但只能订阅一个odom，不能同时订阅两个odom
  use_odometry = false,                     -- 是否使用里程计,如果使用要求一定要有odom的tf
  use_nav_sat = false,                      -- 是否使用gps，默认使用  /fix话题
  use_landmarks = false,                    -- 是否使用landmark

  --num_laser_scans/num_point_clouds 单线点云与多线点云的话题的数量, 可以同时为 1,代表订阅一个单线雷达数据(topic)或者一个多线雷达数据(topic)，为2表示可以订阅两个单线的topic或者多线雷达， 不可以同时为 0
  num_laser_scans = 0,                      -- 是否使用单线激光数据  ----常用
  num_multi_echo_laser_scans = 0,           -- 是否使用multi_echo_laser_scans数据，多声波雷达数据，很少使用到
  num_subdivisions_per_laser_scan = 1,      -- 1帧数据被分成几次处理,一般为1
  num_point_clouds = 1,                     -- 是否使用点云数据 ----常用
  
  lookup_transform_timeout_sec = 0.2,       -- 查找tf时的超时时间
  submap_publish_period_sec = 0.3,          -- 发布数据的时间间隔
  pose_publish_period_sec = 5e-3,
  trajectory_publish_period_sec = 30e-3,

  rangefinder_sampling_ratio = 1.,          -- 传感器数据的采样频率  为1表示来一帧数据用一帧，为0.5表示来2帧数据用1帧，为0.1表示来10帧数据用1帧，好处就是降低计算量，某一个传感器数据不太准确，想用他，但是又不准，那就可以把他的采样频率降低
  odometry_sampling_ratio = 1.,
  fixed_frame_pose_sampling_ratio = 1.,
  imu_sampling_ratio = 1.,
  landmarks_sampling_ratio = 1.,
}

MAP_BUILDER.use_trajectory_builder_2d = true         --建二维图时一定要有这句话, 建三维图就把 2d 改成 3d       对map_builder.lua里面的配置进行重写

TRAJECTORY_BUILDER_2D.use_imu_data = true          --是否使用 imu, 如果用 imu, tracking_frame 一定要设置成 imu 的 link，有imu就用，如果imu特别差的话，就不用。对 trajectory_builder_2d.lua里面的配置进行重写
TRAJECTORY_BUILDER_2D.min_range = 0.3
TRAJECTORY_BUILDER_2D.max_range = 100.
TRAJECTORY_BUILDER_2D.min_z = 0.2                             --点云的最小 z 的范围(实际点云的最小点云小于这个值的话就丢弃不要了), 单线点云不能设置大于 0 的值(因为ie单线点云的z是0，不设置), 
                                                                                                              -- 多线点云的这个值要大于 0，因为多线的会有打向地面的点云，形成一圈一圈的，那建图的时候就会把圈圈建进去，那这时就出现一个问题了
                                                                                                              --当你的传感器既有单线雷达，又有多线雷达的时候，那这个min_z救要出现一个考量了
--TRAJECTORY_BUILDER_2D.max_z = 1.4
--TRAJECTORY_BUILDER_2D.voxel_filter_size = 0.02

--TRAJECTORY_BUILDER_2D.adaptive_voxel_filter.max_length = 0.5
--TRAJECTORY_BUILDER_2D.adaptive_voxel_filter.min_num_points = 200.
--TRAJECTORY_BUILDER_2D.adaptive_voxel_filter.max_range = 50.

--TRAJECTORY_BUILDER_2D.loop_closure_adaptive_voxel_filter.max_length = 0.9
--TRAJECTORY_BUILDER_2D.loop_closure_adaptive_voxel_filter.min_num_points = 100
--TRAJECTORY_BUILDER_2D.loop_closure_adaptive_voxel_filter.max_range = 50.

TRAJECTORY_BUILDER_2D.use_online_correlative_scan_matching = false
TRAJECTORY_BUILDER_2D.ceres_scan_matcher.occupied_space_weight = 1.
TRAJECTORY_BUILDER_2D.ceres_scan_matcher.translation_weight = 1.
TRAJECTORY_BUILDER_2D.ceres_scan_matcher.rotation_weight = 1.
--TRAJECTORY_BUILDER_2D.ceres_scan_matcher.ceres_solver_options.max_num_iterations = 12

--TRAJECTORY_BUILDER_2D.motion_filter.max_distance_meters = 0.1
--TRAJECTORY_BUILDER_2D.motion_filter.max_angle_radians = 0.004
--TRAJECTORY_BUILDER_2D.imu_gravity_time_constant = 1.

TRAJECTORY_BUILDER_2D.submaps.num_range_data = 80.   
TRAJECTORY_BUILDER_2D.submaps.grid_options_2d.resolution = 0.1

POSE_GRAPH.optimize_every_n_nodes = 160.                    --这个160就是2倍的TRAJECTORY_BUILDER_2D.submaps.num_range_data，如果太快了，如果子图没有变化，后端再频繁的优化是没有用的
POSE_GRAPH.constraint_builder.sampling_ratio = 0.3
POSE_GRAPH.constraint_builder.max_constraint_distance = 15.
POSE_GRAPH.constraint_builder.min_score = 0.48
POSE_GRAPH.constraint_builder.global_localization_min_score = 0.60

return options
